package net.minecraft.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;

public class WorldWorker
{
  public String Name;
  private World localWorld;
  private BufferedWriter SettingsWriter;
  private HashMap<String, String> ReadedSettings = new HashMap();
  public Random rand;
  public BiomeBase currentBiome;
  private BiomeBase[] biomeList;
  String seedValue;
  private boolean oldGen;
  private double biomeSize;
  private double minMoisture;
  private double maxMoisture;
  private double minTemperature;
  private double maxTemperature;
  private double snowThreshold;
  private double iceThreshold;
  private boolean muddySwamps;
  private boolean claySwamps;
  private int swampSize;
  private boolean waterlessDeserts;
  private boolean desertDirt;
  private int desertDirtFrequency;
  private boolean removeSurfaceDirtFromDesert;
  private boolean undergroundLakes;
  private boolean undergroundLakesInAir;
  private int undergroundLakeFrequency;
  private int undergroundLakeRarity;
  private int undergroundLakeMinSize;
  private int undergroundLakeMaxSize;
  private int undergroundLakeMinAltitude;
  private int undergroundLakeMaxAltitude;
  private int caveRarity;
  private int caveFrequency;
  private int caveMinAltitude;
  private int caveMaxAltitude;
  private int individualCaveRarity;
  private int caveSystemFrequency;
  private int caveSystemPocketChance;
  private int caveSystemPocketMinSize;
  private int caveSystemPocketMaxSize;
  private boolean evenCaveDistribution;
  private int dungeonRarity;
  private int dungeonFrequency;
  private int dungeonMinAltitude;
  private int dungeonMaxAltitude;
  private int lavaLevelMin;
  private int lavaLevelMax;
  private int waterLevel;
  private double maxAverageHeight;
  private double maxAverageDepth;
  private double fractureHorizontal;
  private double fractureVertical;
  private double volatility1;
  private double volatility2;
  private double volatilityWeight1;
  private double volatilityWeight2;
  private boolean disableBedrock;
  private boolean flatBedrock;
  private boolean bedrockobsidian;
  private boolean disableNotchPonds;
  private boolean removeSurfaceStone;
  private HashMap<Byte, Byte> replaceBlocks = new HashMap();

  private static HashMap<String, WorldWorker> Worlds = new HashMap();
  public ObjectSpawner Spawner;
  private String worldSaveFolder;
  private String minecraftFolder;

  public static void Add(WorldWorker wrk)
  {
    Worlds.put(wrk.Name, wrk);
  }

  public static WorldWorker GetByName(String name)
  {
    return (WorldWorker)Worlds.get(name);
  }

  public WorldWorker(World w)
  {
    this.localWorld = w;
    this.Name = this.localWorld.worldData.name;

    File minecraftFolderF = new File(WorldWorker.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    minecraftFolderF = new File(minecraftFolderF.getParentFile().toString().replace("%20", " "));
    this.minecraftFolder = minecraftFolderF.toString().replace("%20", " ");
    this.worldSaveFolder = (minecraftFolderF.toString().replace("%20", " ") + "/" + this.Name);

    this.Spawner = new ObjectSpawner(this);

    ReadSettings();
    CorrectSettings();
    WriteSettings();
    this.Spawner.RegisterBOBPlugins();

    this.rand = new Random(w.getSeed());

    System.out.println("PhoenixTerrainMod Bukkit Release 1 (Bugfix 6) Loaded!");
  }

  public void CorrectSettings()
  {
    this.biomeSize = (this.biomeSize <= 0.0D ? 4.9E-324D : this.biomeSize);
    this.minMoisture = (this.minMoisture < 0.0D ? 0.0D : this.minMoisture > 1.0D ? 1.0D : this.minMoisture);
    this.minTemperature = (this.minTemperature < 0.0D ? 0.0D : this.minTemperature > 1.0D ? 1.0D : this.minTemperature);
    this.maxMoisture = (this.maxMoisture > 1.0D ? 1.0D : this.maxMoisture < this.minMoisture ? this.minMoisture : this.maxMoisture);
    this.maxTemperature = (this.maxTemperature > 1.0D ? 1.0D : this.maxTemperature < this.minTemperature ? this.minTemperature : this.maxTemperature);
    this.snowThreshold = (this.snowThreshold < -1.0D ? -1.0D : this.snowThreshold > 1.0D ? 1.0D : this.snowThreshold);
    this.iceThreshold = (this.iceThreshold < -1.0D ? -1.0D : this.iceThreshold > 1.0D ? 1.0D : this.iceThreshold);

    this.caveRarity = (this.caveRarity < 0 ? 0 : this.caveRarity > 100 ? 100 : this.caveRarity);
    this.caveFrequency = (this.caveFrequency < 0 ? 0 : this.caveFrequency);
    this.caveMinAltitude = (this.caveMinAltitude < 0 ? 0 : this.caveMinAltitude > BiomeTerrainValues.yLimit.intValue() - 1 ? BiomeTerrainValues.yLimit.intValue() - 1 : this.caveMinAltitude);
    this.caveMaxAltitude = (this.caveMaxAltitude > BiomeTerrainValues.yLimit.intValue() ? BiomeTerrainValues.yLimit.intValue() : this.caveMaxAltitude <= this.caveMinAltitude ? this.caveMinAltitude + 1 : this.caveMaxAltitude);
    this.individualCaveRarity = (this.individualCaveRarity < 0 ? 0 : this.individualCaveRarity);
    this.caveSystemFrequency = (this.caveSystemFrequency < 0 ? 0 : this.caveSystemFrequency);
    this.caveSystemPocketChance = (this.caveSystemPocketChance < 0 ? 0 : this.caveSystemPocketChance > 100 ? 100 : this.caveSystemPocketChance);
    this.caveSystemPocketMinSize = (this.caveSystemPocketMinSize < 0 ? 0 : this.caveSystemPocketMinSize);
    this.caveSystemPocketMaxSize = (this.caveSystemPocketMaxSize <= this.caveSystemPocketMinSize ? this.caveSystemPocketMinSize + 1 : this.caveSystemPocketMaxSize);

    this.dungeonRarity = (this.dungeonRarity < 0 ? 0 : this.dungeonRarity > 100 ? 100 : this.dungeonRarity);
    this.dungeonFrequency = (this.dungeonFrequency < 0 ? 0 : this.dungeonFrequency);
    this.dungeonMinAltitude = (this.dungeonMinAltitude < 0 ? 0 : this.dungeonMinAltitude > BiomeTerrainValues.yLimit.intValue() - 1 ? BiomeTerrainValues.yLimit.intValue() - 1 : this.dungeonMinAltitude);
    this.dungeonMaxAltitude = (this.dungeonMaxAltitude > BiomeTerrainValues.yLimit.intValue() ? BiomeTerrainValues.yLimit.intValue() : this.dungeonMaxAltitude <= this.dungeonMinAltitude ? this.dungeonMinAltitude + 1 : this.dungeonMaxAltitude);

    this.lavaLevelMin = (this.lavaLevelMin < 0 ? 0 : this.lavaLevelMin > BiomeTerrainValues.yLimit.intValue() - 1 ? BiomeTerrainValues.yLimit.intValue() - 1 : this.lavaLevelMin);
    this.lavaLevelMax = (this.lavaLevelMax > BiomeTerrainValues.yLimit.intValue() ? BiomeTerrainValues.yLimit.intValue() : this.lavaLevelMax < this.lavaLevelMin ? this.lavaLevelMin : this.lavaLevelMax);

    this.undergroundLakeRarity = (this.undergroundLakeRarity < 0 ? 0 : this.undergroundLakeRarity > 100 ? 100 : this.undergroundLakeRarity);
    this.undergroundLakeFrequency = (this.undergroundLakeFrequency < 0 ? 0 : this.undergroundLakeFrequency);
    this.undergroundLakeMinSize = (this.undergroundLakeMinSize < 25 ? 25 : this.undergroundLakeMinSize);
    this.undergroundLakeMaxSize = (this.undergroundLakeMaxSize <= this.undergroundLakeMinSize ? this.undergroundLakeMinSize + 1 : this.undergroundLakeMaxSize);
    this.undergroundLakeMinAltitude = (this.undergroundLakeMinAltitude < 0 ? 0 : this.undergroundLakeMinAltitude > BiomeTerrainValues.yLimit.intValue() - 1 ? BiomeTerrainValues.yLimit.intValue() - 1 : this.undergroundLakeMinAltitude);
    this.undergroundLakeMaxAltitude = (this.undergroundLakeMaxAltitude > BiomeTerrainValues.yLimit.intValue() ? BiomeTerrainValues.yLimit.intValue() : this.undergroundLakeMaxAltitude <= this.undergroundLakeMinAltitude ? this.undergroundLakeMinAltitude + 1 : this.undergroundLakeMaxAltitude);

    this.waterLevel = (this.waterLevel < 0 ? 0 : this.waterLevel > BiomeTerrainValues.yLimit.intValue() - 1 ? BiomeTerrainValues.yLimit.intValue() - 1 : this.waterLevel);

    this.Spawner.fixSettingsValues();
  }

  public void ReadSettings()
  {
    BufferedReader SettingsReader = null;

    File f = new File(this.worldSaveFolder, BiomeTerrainValues.biomeTerrainSettingsName.stringValue());
    if (!f.exists())
    {
      f = new File(this.minecraftFolder, BiomeTerrainValues.biomeTerrainSettingsName.stringValue());
    }
    try
    {
      SettingsReader = new BufferedReader(new FileReader(f));
      String thisLine;
      while ((thisLine = SettingsReader.readLine()) != null)
      {
        if (thisLine.toLowerCase().contains(":"))
          this.ReadedSettings.put(thisLine.split(":")[0].trim(), thisLine.split(":")[1].trim());
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();

      if (SettingsReader != null)
        try
        {
          SettingsReader.close();
        }
        catch (IOException localIOException1)
        {
        }
    }
    finally
    {
      if (SettingsReader != null)
        try
        {
          SettingsReader.close();
        }
        catch (IOException localIOException2)
        {
        }
    }
    ReadWorldSettings();
    this.Spawner.readSettings();
  }

  private void ReadWorldSettings()
  {
	this.oldGen = ReadModSettins(BiomeTerrainValues.oldGen.name(), BiomeTerrainValues.oldGen.booleanValue());
    this.biomeSize = ReadModSettins(BiomeTerrainValues.biomeSize.name(), BiomeTerrainValues.biomeSize.doubleValue());
    this.minMoisture = ReadModSettins(BiomeTerrainValues.minMoisture.name(), BiomeTerrainValues.minMoisture.doubleValue());
    this.maxMoisture = ReadModSettins(BiomeTerrainValues.maxMoisture.name(), BiomeTerrainValues.maxMoisture.doubleValue());
    this.minTemperature = ReadModSettins(BiomeTerrainValues.minTemperature.name(), BiomeTerrainValues.minTemperature.doubleValue());
    this.maxTemperature = ReadModSettins(BiomeTerrainValues.maxTemperature.name(), BiomeTerrainValues.maxTemperature.doubleValue());
    this.snowThreshold = ReadModSettins(BiomeTerrainValues.snowThreshold.name(), BiomeTerrainValues.snowThreshold.doubleValue());
    this.iceThreshold = ReadModSettins(BiomeTerrainValues.iceThreshold.name(), BiomeTerrainValues.iceThreshold.doubleValue());

    this.muddySwamps = ReadModSettins(BiomeTerrainValues.muddySwamps.name(), BiomeTerrainValues.muddySwamps.booleanValue().booleanValue());
    this.claySwamps = ReadModSettins(BiomeTerrainValues.claySwamps.name(), BiomeTerrainValues.claySwamps.booleanValue().booleanValue());
    this.swampSize = ReadModSettins(BiomeTerrainValues.swampSize.name(), BiomeTerrainValues.swampSize.intValue());

    this.waterlessDeserts = ReadModSettins(BiomeTerrainValues.waterlessDeserts.name(), BiomeTerrainValues.waterlessDeserts.booleanValue().booleanValue());
    this.removeSurfaceDirtFromDesert = ReadModSettins(BiomeTerrainValues.removeSurfaceDirtFromDesert.name(), BiomeTerrainValues.removeSurfaceDirtFromDesert.booleanValue().booleanValue());
    this.desertDirt = ReadModSettins(BiomeTerrainValues.desertDirt.name(), BiomeTerrainValues.desertDirt.booleanValue().booleanValue());
    this.desertDirtFrequency = ReadModSettins(BiomeTerrainValues.desertDirtFrequency.name(), BiomeTerrainValues.desertDirtFrequency.intValue());

    this.caveRarity = ReadModSettins(BiomeTerrainValues.caveRarity.name(), BiomeTerrainValues.caveRarity.intValue());
    this.caveFrequency = ReadModSettins(BiomeTerrainValues.caveFrequency.name(), BiomeTerrainValues.caveFrequency.intValue());
    this.caveMinAltitude = ReadModSettins(BiomeTerrainValues.caveMinAltitude.name(), BiomeTerrainValues.caveMinAltitude.intValue());
    this.caveMaxAltitude = ReadModSettins(BiomeTerrainValues.caveMaxAltitude.name(), BiomeTerrainValues.caveMaxAltitude.intValue());
    this.individualCaveRarity = ReadModSettins(BiomeTerrainValues.individualCaveRarity.name(), BiomeTerrainValues.individualCaveRarity.intValue());
    this.caveSystemFrequency = ReadModSettins(BiomeTerrainValues.caveSystemFrequency.name(), BiomeTerrainValues.caveSystemFrequency.intValue());
    this.caveSystemPocketChance = ReadModSettins(BiomeTerrainValues.caveSystemPocketChance.name(), BiomeTerrainValues.caveSystemPocketChance.intValue());
    this.caveSystemPocketMinSize = ReadModSettins(BiomeTerrainValues.caveSystemPocketMinSize.name(), BiomeTerrainValues.caveSystemPocketMinSize.intValue());
    this.caveSystemPocketMaxSize = ReadModSettins(BiomeTerrainValues.caveSystemPocketMaxSize.name(), BiomeTerrainValues.caveSystemPocketMaxSize.intValue());
    this.evenCaveDistribution = ReadModSettins(BiomeTerrainValues.evenCaveDistribution.name(), BiomeTerrainValues.evenCaveDistribution.booleanValue().booleanValue());

    this.dungeonRarity = ReadModSettins(BiomeTerrainValues.dungeonRarity.name(), BiomeTerrainValues.dungeonRarity.intValue());
    this.dungeonFrequency = ReadModSettins(BiomeTerrainValues.dungeonFrequency.name(), BiomeTerrainValues.dungeonFrequency.intValue());
    this.dungeonMinAltitude = ReadModSettins(BiomeTerrainValues.dungeonMinAltitude.name(), BiomeTerrainValues.dungeonMinAltitude.intValue());
    this.dungeonMaxAltitude = ReadModSettins(BiomeTerrainValues.dungeonMaxAltitude.name(), BiomeTerrainValues.dungeonMaxAltitude.intValue());

    this.lavaLevelMin = ReadModSettins(BiomeTerrainValues.lavaLevelMin.name(), BiomeTerrainValues.lavaLevelMin.intValue());
    this.lavaLevelMax = ReadModSettins(BiomeTerrainValues.lavaLevelMax.name(), BiomeTerrainValues.lavaLevelMax.intValue());

    this.undergroundLakes = ReadModSettins(BiomeTerrainValues.undergroundLakes.name(), BiomeTerrainValues.undergroundLakes.booleanValue().booleanValue());
    this.undergroundLakesInAir = ReadModSettins(BiomeTerrainValues.undergroundLakesInAir.name(), BiomeTerrainValues.undergroundLakesInAir.booleanValue().booleanValue());
    this.undergroundLakeFrequency = ReadModSettins(BiomeTerrainValues.undergroundLakeFrequency.name(), BiomeTerrainValues.undergroundLakeFrequency.intValue());
    this.undergroundLakeRarity = ReadModSettins(BiomeTerrainValues.undergroundLakeRarity.name(), BiomeTerrainValues.undergroundLakeRarity.intValue());
    this.undergroundLakeMinSize = ReadModSettins(BiomeTerrainValues.undergroundLakeMinSize.name(), BiomeTerrainValues.undergroundLakeMinSize.intValue());
    this.undergroundLakeMaxSize = ReadModSettins(BiomeTerrainValues.undergroundLakeMaxSize.name(), BiomeTerrainValues.undergroundLakeMaxSize.intValue());
    this.undergroundLakeMinAltitude = ReadModSettins(BiomeTerrainValues.undergroundLakeMinAltitude.name(), BiomeTerrainValues.undergroundLakeMinAltitude.intValue());
    this.undergroundLakeMaxAltitude = ReadModSettins(BiomeTerrainValues.undergroundLakeMaxAltitude.name(), BiomeTerrainValues.undergroundLakeMaxAltitude.intValue());

    this.waterLevel = ReadModSettins(BiomeTerrainValues.waterLevel.name(), BiomeTerrainValues.waterLevel.intValue());
    this.maxAverageHeight = ReadModSettins(BiomeTerrainValues.maxAverageHeight.name(), BiomeTerrainValues.maxAverageHeight.doubleValue());
    this.maxAverageDepth = ReadModSettins(BiomeTerrainValues.maxAverageDepth.name(), BiomeTerrainValues.maxAverageDepth.doubleValue());
    this.fractureHorizontal = ReadModSettins(BiomeTerrainValues.fractureHorizontal.name(), BiomeTerrainValues.fractureHorizontal.doubleValue());
    this.fractureVertical = ReadModSettins(BiomeTerrainValues.fractureVertical.name(), BiomeTerrainValues.fractureVertical.doubleValue());
    this.volatility1 = ReadModSettins(BiomeTerrainValues.volatility1.name(), BiomeTerrainValues.volatility1.doubleValue());
    this.volatility2 = ReadModSettins(BiomeTerrainValues.volatility2.name(), BiomeTerrainValues.volatility2.doubleValue());
    this.volatilityWeight1 = ReadModSettins(BiomeTerrainValues.volatilityWeight1.name(), BiomeTerrainValues.volatilityWeight1.doubleValue());
    this.volatilityWeight2 = ReadModSettins(BiomeTerrainValues.volatilityWeight2.name(), BiomeTerrainValues.volatilityWeight2.doubleValue());

    this.disableBedrock = ReadModSettins(BiomeTerrainValues.disableBedrock.name(), BiomeTerrainValues.disableBedrock.booleanValue().booleanValue());
    this.flatBedrock = ReadModSettins(BiomeTerrainValues.flatBedrock.name(), BiomeTerrainValues.flatBedrock.booleanValue().booleanValue());
    this.bedrockobsidian = ReadModSettins(BiomeTerrainValues.bedrockobsidian.name(), BiomeTerrainValues.bedrockobsidian.booleanValue().booleanValue());

    this.disableNotchPonds = ReadModSettins(BiomeTerrainValues.disableNotchPonds.name(), BiomeTerrainValues.disableNotchPonds.booleanValue().booleanValue());

    this.removeSurfaceStone = ReadModSettins(BiomeTerrainValues.removeSurfaceStone.name(), BiomeTerrainValues.removeSurfaceStone.booleanValue().booleanValue());

    Iterator i = this.ReadedSettings.entrySet().iterator();
    while (i.hasNext())
    {
      Map.Entry me = (Map.Entry)i.next();
      if (((String)me.getKey()).contains("replace"))
        this.replaceBlocks.put(Byte.valueOf(((String)me.getKey()).replace("replace", "")), Byte.valueOf((String)me.getValue()));
    }
  }

  public String ReadModSettins(String settingsName, String defaultValue)
  {
    if (this.ReadedSettings.containsKey(settingsName)) {
      return String.valueOf(this.ReadedSettings.get(settingsName));
    }
    return defaultValue;
  }

  public int ReadModSettins(String settingsName, int defaultValue) {
    if (this.ReadedSettings.containsKey(settingsName)) {
      return Integer.valueOf((String)this.ReadedSettings.get(settingsName)).intValue();
    }
    return defaultValue;
  }

  public double ReadModSettins(String settingsName, double defaultValue)
  {
    if (this.ReadedSettings.containsKey(settingsName)) {
      return Double.valueOf((String)this.ReadedSettings.get(settingsName)).doubleValue();
    }
    return defaultValue;
  }

  public boolean ReadModSettins(String settingsName, boolean defaultValue)
  {
    if (this.ReadedSettings.containsKey(settingsName)) {
      return Boolean.valueOf((String)this.ReadedSettings.get(settingsName)).booleanValue();
    }
    return defaultValue;
  }

  public void WriteSettings()
  {
    File f = new File(this.worldSaveFolder, BiomeTerrainValues.biomeTerrainSettingsName.stringValue());
    try
    {
      this.SettingsWriter = new BufferedWriter(new FileWriter(f, false));

      WriteWorldSettings();
      this.Spawner.writeSettings();
    }
    catch (IOException e)
    {
      e.printStackTrace();

      if (this.SettingsWriter != null)
        try
        {
          this.SettingsWriter.close();
        }
        catch (IOException localIOException1)
        {
        }
    }
    finally
    {
      if (this.SettingsWriter != null)
        try
        {
          this.SettingsWriter.close();
        }
        catch (IOException localIOException2)
        {
        }
    }
  }

  private void WriteWorldSettings() throws IOException
  {
    WriteModTitleSettings("Biome Mod - All Biome Variables");
    WriteModSettings(BiomeTerrainValues.oldGen.name(), this.oldGen);
    WriteModSettings(BiomeTerrainValues.biomeSize.name(), this.biomeSize);
    WriteModSettings(BiomeTerrainValues.minMoisture.name(), this.minMoisture);
    WriteModSettings(BiomeTerrainValues.maxMoisture.name(), this.maxMoisture);
    WriteModSettings(BiomeTerrainValues.minTemperature.name(), this.minTemperature);
    WriteModSettings(BiomeTerrainValues.maxTemperature.name(), this.maxTemperature);
    WriteModSettings(BiomeTerrainValues.snowThreshold.name(), this.snowThreshold);
    WriteModSettings(BiomeTerrainValues.iceThreshold.name(), this.iceThreshold);

    WriteModTitleSettings("Biome Mod - Swamp Biome Variables");
    WriteModSettings(BiomeTerrainValues.muddySwamps.name(), this.muddySwamps);
    WriteModSettings(BiomeTerrainValues.claySwamps.name(), this.claySwamps);
    WriteModSettings(BiomeTerrainValues.swampSize.name(), this.swampSize);

    WriteModTitleSettings("Biome Mod - Desert Biome Variables");
    WriteModSettings(BiomeTerrainValues.waterlessDeserts.name(), this.waterlessDeserts);
    WriteModSettings(BiomeTerrainValues.removeSurfaceDirtFromDesert.name(), this.removeSurfaceDirtFromDesert);
    WriteModSettings(BiomeTerrainValues.desertDirt.name(), this.desertDirt);
    WriteModSettings(BiomeTerrainValues.desertDirtFrequency.name(), this.desertDirtFrequency);

    WriteModTitleSettings("Cave Mod - Cave Variables");
    WriteModSettings(BiomeTerrainValues.caveRarity.name(), this.caveRarity);
    WriteModSettings(BiomeTerrainValues.caveFrequency.name(), this.caveFrequency);
    WriteModSettings(BiomeTerrainValues.caveMinAltitude.name(), this.caveMinAltitude);
    WriteModSettings(BiomeTerrainValues.caveMaxAltitude.name(), this.caveMaxAltitude);
    WriteModSettings(BiomeTerrainValues.individualCaveRarity.name(), this.individualCaveRarity);
    WriteModSettings(BiomeTerrainValues.caveSystemFrequency.name(), this.caveSystemFrequency);
    WriteModSettings(BiomeTerrainValues.caveSystemPocketChance.name(), this.caveSystemPocketChance);
    WriteModSettings(BiomeTerrainValues.caveSystemPocketMinSize.name(), this.caveSystemPocketMinSize);
    WriteModSettings(BiomeTerrainValues.caveSystemPocketMaxSize.name(), this.caveSystemPocketMaxSize);
    WriteModSettings(BiomeTerrainValues.evenCaveDistribution.name(), this.evenCaveDistribution);

    WriteModTitleSettings("Cave Mod - Dungeon Variables");
    WriteModSettings(BiomeTerrainValues.dungeonRarity.name(), this.dungeonRarity);
    WriteModSettings(BiomeTerrainValues.dungeonFrequency.name(), this.dungeonFrequency);
    WriteModSettings(BiomeTerrainValues.dungeonMinAltitude.name(), this.dungeonMinAltitude);
    WriteModSettings(BiomeTerrainValues.dungeonMaxAltitude.name(), this.dungeonMaxAltitude);

    WriteModTitleSettings("Cave Mod - Lava Pool Variables");
    WriteModSettings(BiomeTerrainValues.lavaLevelMin.name(), this.lavaLevelMin);
    WriteModSettings(BiomeTerrainValues.lavaLevelMax.name(), this.lavaLevelMax);

    WriteModTitleSettings("Underground Lake Mod - Underground Lake Variables");
    WriteModSettings(BiomeTerrainValues.undergroundLakes.name(), this.undergroundLakes);
    WriteModSettings(BiomeTerrainValues.undergroundLakesInAir.name(), this.undergroundLakesInAir);
    WriteModSettings(BiomeTerrainValues.undergroundLakeFrequency.name(), this.undergroundLakeFrequency);
    WriteModSettings(BiomeTerrainValues.undergroundLakeRarity.name(), this.undergroundLakeRarity);
    WriteModSettings(BiomeTerrainValues.undergroundLakeMinSize.name(), this.undergroundLakeMinSize);
    WriteModSettings(BiomeTerrainValues.undergroundLakeMaxSize.name(), this.undergroundLakeMaxSize);
    WriteModSettings(BiomeTerrainValues.undergroundLakeMinAltitude.name(), this.undergroundLakeMinAltitude);
    WriteModSettings(BiomeTerrainValues.undergroundLakeMaxAltitude.name(), this.undergroundLakeMaxAltitude);

    WriteModTitleSettings("Terrain Mod - Terrain Variables");
    WriteModSettings(BiomeTerrainValues.waterLevel.name(), this.waterLevel);
    WriteModSettings(BiomeTerrainValues.maxAverageHeight.name(), this.maxAverageHeight);
    WriteModSettings(BiomeTerrainValues.maxAverageDepth.name(), this.maxAverageDepth);
    WriteModSettings(BiomeTerrainValues.fractureHorizontal.name(), this.fractureHorizontal);
    WriteModSettings(BiomeTerrainValues.fractureVertical.name(), this.fractureVertical);
    WriteModSettings(BiomeTerrainValues.volatility1.name(), this.volatility1);
    WriteModSettings(BiomeTerrainValues.volatility2.name(), this.volatility2);
    WriteModSettings(BiomeTerrainValues.volatilityWeight1.name(), this.volatilityWeight1);
    WriteModSettings(BiomeTerrainValues.volatilityWeight2.name(), this.volatilityWeight2);

    WriteModTitleSettings("Terrain Mod - Bedrock Variables");
    WriteModSettings(BiomeTerrainValues.disableBedrock.name(), this.disableBedrock);
    WriteModSettings(BiomeTerrainValues.flatBedrock.name(), this.flatBedrock);
    WriteModSettings(BiomeTerrainValues.bedrockobsidian.name(), this.bedrockobsidian);

    WriteModTitleSettings("Terrain Mod - Temporary Variables");
    WriteModSettings(BiomeTerrainValues.disableNotchPonds.name(), this.disableNotchPonds);

    WriteModTitleSettings("Replace Block Mod - Replace Variables");
    WriteModSettings(BiomeTerrainValues.removeSurfaceStone.name(), this.removeSurfaceStone);

    Iterator i = this.replaceBlocks.entrySet().iterator();
    while (i.hasNext())
    {
      Map.Entry me = (Map.Entry)i.next();
      WriteModSettings("replace" + ((Byte)me.getKey()).toString(), ((Byte)me.getValue()).toString());
    }
  }

  public void WriteModSettings(String settingsName, int settingsValue)
    throws IOException
  {
    this.SettingsWriter.write(settingsName + ":" + Integer.toString(settingsValue));
    this.SettingsWriter.newLine();
  }

  public void WriteModSettings(String settingsName, double settingsValue) throws IOException
  {
    this.SettingsWriter.write(settingsName + ":" + Double.toString(settingsValue));
    this.SettingsWriter.newLine();
  }

  public void WriteModSettings(String settingsName, boolean settingsValue) throws IOException
  {
    this.SettingsWriter.write(settingsName + ":" + Boolean.toString(settingsValue));
    this.SettingsWriter.newLine();
  }

  public void WriteModSettings(String settingsName, String settingsValue) throws IOException
  {
    this.SettingsWriter.write(settingsName + ":" + settingsValue);
    this.SettingsWriter.newLine();
  }

  public void WriteModTitleSettings(String title) throws IOException
  {
    this.SettingsWriter.newLine();
    this.SettingsWriter.write("<" + title + ">");
    this.SettingsWriter.newLine();
  }

  public void processChunkBlocks(byte[] blocks, BiomeBase[] biomes)
  {
    this.biomeList = biomes;

    for (int x = 0; x < BiomeTerrainValues.xLimit.intValue(); x++)
      for (int z = 0; z < BiomeTerrainValues.zLimit.intValue(); z++)
      {
        this.currentBiome = this.biomeList[(x * BiomeTerrainValues.zLimit.intValue() + z)];
        for (int y = 0; y < BiomeTerrainValues.yLimit.intValue(); y++)
        {
          int block = y + z * BiomeTerrainValues.yLimit.intValue() + x * BiomeTerrainValues.yLimit.intValue() * BiomeTerrainValues.zLimit.intValue();
          if (block >= BiomeTerrainValues.maxChunkBlockValue.intValue() - 1)
            continue;
          if ((this.removeSurfaceDirtFromDesert) && (this.currentBiome == BiomeTerrainValues.Desert.biomeValue()) && ((blocks[block] == BiomeTerrainValues.grass.byteValue().byteValue()) || (blocks[block] == BiomeTerrainValues.dirt.byteValue().byteValue())) && (blocks[(block + 1)] == BiomeTerrainValues.air.byteValue().byteValue()))
            blocks[block] = BiomeTerrainValues.sand.byteValue().byteValue();
          if ((this.desertDirt) && (this.currentBiome == BiomeTerrainValues.Desert.biomeValue()) && (this.desertDirtFrequency > 0) && (this.rand.nextInt(this.desertDirtFrequency * BiomeTerrainValues.xLimit.intValue() * BiomeTerrainValues.zLimit.intValue()) == 0) && (blocks[block] == BiomeTerrainValues.sand.byteValue().byteValue()) && (blocks[(block + 1)] == BiomeTerrainValues.air.byteValue().byteValue()))
            blocks[block] = BiomeTerrainValues.dirt.byteValue().byteValue();
          if ((this.waterlessDeserts) && (this.currentBiome == BiomeTerrainValues.Desert.biomeValue()) && ((blocks[block] == BiomeTerrainValues.stationarywater.byteValue().byteValue()) || (blocks[block] == BiomeTerrainValues.ice.byteValue().byteValue())))
            blocks[block] = BiomeTerrainValues.sand.byteValue().byteValue();
          if (((this.muddySwamps) || (this.claySwamps)) && (this.currentBiome == BiomeTerrainValues.Swampland.biomeValue()) && ((blocks[block] == BiomeTerrainValues.grass.byteValue().byteValue()) || (blocks[block] == BiomeTerrainValues.dirt.byteValue().byteValue()) || (blocks[block] == BiomeTerrainValues.sand.byteValue().byteValue())))
            createSwamps(blocks, block);
          if ((this.removeSurfaceStone) && (blocks[block] == BiomeTerrainValues.rock.byteValue().byteValue()) && (blocks[(block + 1)] == BiomeTerrainValues.air.byteValue().byteValue()))
            blocks[block] = findNearestStoneReplacement(blocks, block);
          if (this.replaceBlocks.size() > 0)
            blocks[block] = replaceBlock(blocks[block]);
        }
      }
  }

  public void processUndergroundDeposits(int x, int z)
  {
    this.currentBiome = this.localWorld.getWorldChunkManager().getBiome(x + 16, z + 16);

    this.Spawner.processDepositMaterial(x, z, this.dungeonRarity, this.dungeonFrequency, this.dungeonMinAltitude, this.dungeonMaxAltitude, -1, BiomeTerrainValues.mobspawner.byteValue().byteValue(), false);

    this.Spawner.processUndergroundDeposits(x, z);

    if (this.undergroundLakes)
      processUndergroundLakes(x, z);
  }

  public void processAboveGroundMaterials(int x, int z)
  {
    this.currentBiome = this.localWorld.getWorldChunkManager().getBiome(x + 16, z + 16);
    this.Spawner.processAboveGroundMaterials(x, z);
  }

  public void processHellMaterials(int x, int z)
  {
    this.Spawner.processHellMaterials(x, z);
  }

  public int processTrees(BiomeBase biome, int treeDensity, int treeDensityVariation)
  {
    this.currentBiome = biome;

    return this.Spawner.processTrees(treeDensity, treeDensityVariation);
  }

  public void processUndergroundLakes(int x, int z)
  {
    for (int i = 0; i < this.undergroundLakeFrequency; i++)
    {
      if (this.rand.nextInt(100) >= this.undergroundLakeRarity)
        continue;
      int xR = x + this.rand.nextInt(16);
      int yR = this.rand.nextInt(this.undergroundLakeMaxAltitude - this.undergroundLakeMinAltitude) + this.undergroundLakeMinAltitude;
      int zR = z + this.rand.nextInt(16);
      createUndergroundLake(this.rand.nextInt(this.undergroundLakeMaxSize - this.undergroundLakeMinSize) + this.undergroundLakeMinSize, xR, yR, zR);
    }
  }

  private byte findNearestStoneReplacement(byte[] blocks, int block)
  {
    for (int w = 1; w < 16; w++)
      for (int y = 0; y <= 2; y++)
        for (int x = -1 * w; x <= 1 * w; x++)
          for (int z = -1 * w; z <= 1 * w; z++)
          {
            int newBlock = block + (y == 2 ? -1 : y) + z * BiomeTerrainValues.yLimit.intValue() + x * BiomeTerrainValues.yLimit.intValue() * BiomeTerrainValues.zLimit.intValue();
            if ((newBlock < 0) || (newBlock > BiomeTerrainValues.maxChunkBlockValue.intValue() - 1))
              continue;
            if ((blocks[newBlock] == BiomeTerrainValues.grass.byteValue().byteValue()) || (blocks[newBlock] == BiomeTerrainValues.dirt.byteValue().byteValue()) || (blocks[newBlock] == BiomeTerrainValues.sand.byteValue().byteValue()) || (blocks[newBlock] == BiomeTerrainValues.gravel.byteValue().byteValue()) || (blocks[newBlock] == BiomeTerrainValues.clay.byteValue().byteValue()))
              return blocks[newBlock];
          }
    return ((this.currentBiome == BiomeTerrainValues.Desert.biomeValue()) || (this.currentBiome == BiomeTerrainValues.IceDesert.biomeValue()) ? BiomeTerrainValues.sand.byteValue() : BiomeTerrainValues.grass.byteValue()).byteValue();
  }

  private byte replaceBlock(byte block)
  {
    Iterator i = this.replaceBlocks.entrySet().iterator();
    while (i.hasNext())
    {
      Map.Entry me = (Map.Entry)i.next();
      if (((Byte)me.getKey()).byteValue() == block)
        return ((Byte)me.getValue()).byteValue();
    }
    return block;
  }

  private void createSwamps(byte[] blocks, int block)
  {
    int swampSize = this.swampSize < 0 ? 0 : this.swampSize > 15 ? 15 : this.swampSize;

    if (blocks[(block + 1)] == BiomeTerrainValues.stationarywater.byteValue().byteValue())
    {
      if (this.muddySwamps)
        blocks[block] = BiomeTerrainValues.slowsand.byteValue().byteValue();
      else if (this.claySwamps)
        blocks[block] = BiomeTerrainValues.clay.byteValue().byteValue();
      return;
    }

    for (int x = swampSize * -1; x < swampSize + 1; x++)
      for (int z = swampSize * -1; z < swampSize + 1; z++)
      {
        int newBlock = block + z * BiomeTerrainValues.yLimit.intValue() + x * BiomeTerrainValues.yLimit.intValue() * BiomeTerrainValues.zLimit.intValue();
        if ((newBlock < 0) || (newBlock > BiomeTerrainValues.maxChunkBlockValue.intValue() - 1))
          continue;
        if (blocks[newBlock] != BiomeTerrainValues.stationarywater.byteValue().byteValue())
          continue;
        if (this.muddySwamps)
          blocks[block] = BiomeTerrainValues.slowsand.byteValue().byteValue();
        else if (this.claySwamps)
          blocks[block] = BiomeTerrainValues.clay.byteValue().byteValue();
        return;
      }
  }

  private void createUndergroundLake(int size, int x, int y, int z)
  {
    float mPi = this.rand.nextFloat() * 3.141593F;

    double x1 = x + 8 + sin(mPi) * size / 8.0F;
    double x2 = x + 8 - sin(mPi) * size / 8.0F;
    double z1 = z + 8 + cos(mPi) * size / 8.0F;
    double z2 = z + 8 - cos(mPi) * size / 8.0F;

    double y1 = y + this.rand.nextInt(3) + 2;
    double y2 = y + this.rand.nextInt(3) + 2;

    for (int i = 0; i <= size; i++)
    {
      double xAdjusted = x1 + (x2 - x1) * i / size;
      double yAdjusted = y1 + (y2 - y1) * i / size;
      double zAdjusted = z1 + (z2 - z1) * i / size;

      double horizontalSizeMultiplier = this.rand.nextDouble() * size / 16.0D;
      double verticalSizeMultiplier = this.rand.nextDouble() * size / 32.0D;
      double horizontalSize = (sin(i * 3.141593F / size) + 1.0F) * horizontalSizeMultiplier + 1.0D;
      double verticalSize = (sin(i * 3.141593F / size) + 1.0F) * verticalSizeMultiplier + 1.0D;

      for (int xLake = (int)(xAdjusted - horizontalSize / 2.0D); xLake <= (int)(xAdjusted + horizontalSize / 2.0D); xLake++)
        for (int yLake = (int)(yAdjusted - verticalSize / 2.0D); yLake <= (int)(yAdjusted + verticalSize / 2.0D); yLake++)
          for (int zLake = (int)(zAdjusted - horizontalSize / 2.0D); zLake <= (int)(zAdjusted + horizontalSize / 2.0D); zLake++)
          {
            double xBounds = (xLake + 0.5D - xAdjusted) / (horizontalSize / 2.0D);
            double yBounds = (yLake + 0.5D - yAdjusted) / (verticalSize / 2.0D);
            double zBounds = (zLake + 0.5D - zAdjusted) / (horizontalSize / 2.0D);
            if (xBounds * xBounds + yBounds * yBounds + zBounds * zBounds >= 1.0D)
              continue;
            int uBlock = this.localWorld.getTypeId(xLake, yLake - 1, zLake);
            if ((yLake < y + 2) && ((this.undergroundLakesInAir) || (uBlock != BiomeTerrainValues.air.byteValue().byteValue())))
              this.localWorld.a(xLake, yLake, zLake, BiomeTerrainValues.water.byteValue().byteValue());
            else
              this.localWorld.a(xLake, yLake, zLake, BiomeTerrainValues.air.byteValue().byteValue());
          }
    }
  }

  public static float sin(float n)
  {
    return MathHelper.sin(n);
  }

  public static float cos(float n)
  {
    return MathHelper.cos(n);
  }

  public World getWorld()
  {
    return this.localWorld;
  }
  public boolean getOldGen()
  {
	  return this.oldGen;
  }
  public double getBiomeSize()
  {
    return this.biomeSize;
  }

  public double getMinimumTemperature()
  {
    return this.minTemperature;
  }

  public double getMaximumTemperature()
  {
    return this.maxTemperature;
  }

  public double getMinimumMoisture()
  {
    return this.minMoisture;
  }

  public double getMaximumMoisture()
  {
    return this.maxMoisture;
  }

  public double getSnowThreshold()
  {
    return this.snowThreshold;
  }

  public double getIceThreshold()
  {
    return this.iceThreshold;
  }

  public int getCaveRarity()
  {
    return this.caveRarity;
  }

  public int getCaveFrequency()
  {
    return this.caveFrequency;
  }

  public int getCaveMinAltitude()
  {
    return this.caveMinAltitude;
  }

  public int getCaveMaxAltitude()
  {
    return this.caveMaxAltitude;
  }

  public int getIndividualCaveRarity()
  {
    return this.individualCaveRarity;
  }

  public int getCaveSystemFrequency()
  {
    return this.caveSystemFrequency;
  }

  public int getCaveSystemPocketChance()
  {
    return this.caveSystemPocketChance;
  }

  public int getCaveSystemPocketMinSize()
  {
    return this.caveSystemPocketMinSize;
  }

  public int getCaveSystemPocketMaxSize()
  {
    return this.caveSystemPocketMaxSize;
  }

  public boolean getEvenCaveDistribution()
  {
    return this.evenCaveDistribution;
  }

  public int getLavaLevelMin()
  {
    return this.lavaLevelMin;
  }

  public int getLavaLevelMax()
  {
    return this.lavaLevelMax;
  }

  public int getWaterLevel()
  {
    return this.waterLevel;
  }

  public double getMaxAverageHeight()
  {
    return this.maxAverageHeight;
  }

  public double getMaxAverageDepth()
  {
    return this.maxAverageDepth;
  }

  public double getFractureHorizontal()
  {
    return this.fractureHorizontal < 0.0D ? 1.0D / (Math.abs(this.fractureHorizontal) + 1.0D) : this.fractureHorizontal + 1.0D;
  }

  public double getFractureVertical()
  {
    return this.fractureVertical < 0.0D ? 1.0D / (Math.abs(this.fractureVertical) + 1.0D) : this.fractureVertical + 1.0D;
  }

  public double getVolatility1()
  {
    return this.volatility1 < 0.0D ? 1.0D / (Math.abs(this.volatility1) + 1.0D) : this.volatility1 + 1.0D;
  }

  public double getVolatility2()
  {
    return this.volatility2 < 0.0D ? 1.0D / (Math.abs(this.volatility2) + 1.0D) : this.volatility2 + 1.0D;
  }

  public double getVolatilityWeight1()
  {
    return (this.volatilityWeight1 - 0.5D) * 24.0D;
  }

  public double getVolatilityWeight2()
  {
    return (0.5D - this.volatilityWeight2) * 24.0D;
  }

  public boolean createadminium(int y)
  {
    return (!this.disableBedrock) && ((!this.flatBedrock) || ((this.flatBedrock) && (y == 0)));
  }

  public byte getadminium()
  {
    return (this.bedrockobsidian ? BiomeTerrainValues.obsidian.byteValue() : BiomeTerrainValues.adminium.byteValue()).byteValue();
  }

  public boolean getDisableNotchPonds()
  {
    return this.disableNotchPonds;
  }

  public boolean getNotchBiomeTrees()
  {
    return this.Spawner.getNotchBiomeTrees();
  }

  public int getGlobalTreeDensity()
  {
    return this.Spawner.getGlobalTreeDensity();
  }

  public String GetWorldSaveFolder()
  {
    return this.worldSaveFolder;
  }
}